package com.asimplefox.service.impl;

import com.alibaba.fastjson.JSON;
import com.asimplefox.aasr.BaiduAasrService;
import com.asimplefox.aasr.TaskId;
import com.asimplefox.aasr.TaskResult;
import com.asimplefox.configs.FileConfig;
import com.asimplefox.entity.AasrTask;
import com.asimplefox.entity.Vid;
import com.asimplefox.entity.VidList;
import com.asimplefox.mapper.VidMapper;
import com.asimplefox.service.IAasrTaskService;
import com.asimplefox.service.IVidListService;
import com.asimplefox.service.IVidService;
import com.asimplefox.service.abst.ServiceImplAll;
import com.asimplefox.utils.MP4ToAudio;
import com.asimplefox.utils.TranslateUtils;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author kloping
 * @since 2024-10-15
 */
@Service
@Slf4j
public class VidServiceImpl extends ServiceImplAll<VidMapper, Vid> implements IVidService {
    @Autowired
    FileConfig fileConfig;

    @Autowired
    IVidListService vidListService;

    @Override
    public String save(Vid vid0, MultipartFile file, HttpServletResponse response) {
        FileConfig.FileWithPath fwp = null;
        VidList vidList = null;
        try {
            vidList = vidListService.lambdaQuery().eq(VidList::getId, vid0.getVid()).one();
            if (vidList == null) {
                response.setStatus(400);
                return fail("视频列表不存在");
            }
            Vid vid1 = lambdaQuery().eq(Vid::getVid, vid0.getVid()).eq(Vid::getSt, vid0.getSt()).one();
            if (vid1 != null) {
                response.setStatus(400);
                return fail("对应视频列表中对应集目已存在,请先删除或上传其他集目");
            }
            fwp = fileConfig.getFileWithPath("videos/",
                    String.format("%s/%s.%s", vidList.getName(), vid0.getSt(), getSuffix(file.getContentType())));
            try {
                fwp.write(file.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
                response.setStatus(500);
                return error("上传失败");
            }
            vid0.setUrl(fwp.getUrl());
            save(vid0);
            return result(200, "上传成功", Kv.of("id", vid0.getId()), Kv.of("url", vid0.getUrl()));
        } finally {
            if (vid0.getId() != null){
                log.info("start prep submit task for video: {}-{}", vid0.getId(), vid0.getUrl());
                FileConfig.FileWithPath finalFwp = fwp;
                FileConfig.FileWithPath finalOut = fileConfig.getFileWithPath("videos/",
                        String.format("%s/%s.%s", vidList.getName(), vid0.getSt(), "wav"));
                VidList finalVidList = vidList;
                executorService.submit(() -> {
                    MP4ToAudio.mp4ToAudio(finalFwp.getFile(), finalOut.getFile());
                    TaskId taskId = aasrService.create(finalOut.getUrl());
                    aasrTaskService.save(new AasrTask()
                            .setTaskId(taskId.getTask_id())
                            .setStatus(taskId.getTask_status())
                            .setVst(vid0.getSt())
                            .setVlname(finalVidList.getName())
                            .setData("")
                    );
                    log.info("submitted task: {}-{}", taskId.getTask_status(), taskId.getTask_id());
                });
            }
        }
    }

    @Scheduled(cron = "0 0/1 * * * ?")
    public void checkTask() {
        List<AasrTask> list = aasrTaskService.lambdaQuery()
                .eq(AasrTask::getStatus, "Running").or().eq(AasrTask::getStatus, "Created")
                .list();
        for (AasrTask aasrTask : list) {
            TaskResult result = aasrService.query(aasrTask.getTaskId());
            TaskResult.TaskInfo info = result.getTasks_info()[0];

            log.info("query taskid {} status: {}", info.getTask_id(), info.getTask_status());

            if (info.getTask_status().equalsIgnoreCase("success")) {

                FileConfig.FileWithPath finalAasr = fileConfig.getFileWithPath("videos/",
                        String.format("%s/%s.%s", aasrTask.getVlname(), aasrTask.getVst(), "json"));

                finalAasr.write(JSON.toJSONString(info).getBytes());

                FileConfig.FileWithPath finalAasrEn = fileConfig.getFileWithPath("videos/",
                        String.format("%s/%s-en.%s", aasrTask.getVlname(), aasrTask.getVst(), "json"));

                for (TaskResult.DetailedResult detailedResult : info.getTask_result().getDetailed_result()) {
                    String[] ress = detailedResult.getRes();
                    for (int i = 0; i < ress.length; i++) {
                        ress[i] = TranslateUtils.translateToEn(ress[i]);
                    }
                    detailedResult.setRes(ress);
                }
                for (int i = 0; i < info.getTask_result().getResult().length; i++) {
                    info.getTask_result().getResult()[i] = TranslateUtils.translateToEn(info.getTask_result().getResult()[i]);
                }

                finalAasrEn.write(JSON.toJSONString(info).getBytes());

                aasrTaskService.updateById(
                        aasrTask.setStatus(info.getTask_status())
                                .setData(JSON.toJSONString(result)));
            } else {
                if (!aasrTask.getStatus().equalsIgnoreCase(info.getTask_status())) {
                    aasrTaskService.updateById(aasrTask.setStatus(info.getTask_status()));
                }
            }
        }
    }

    @Autowired
    IAasrTaskService aasrTaskService;

    @Autowired
    BaiduAasrService aasrService;

    @Autowired
    ExecutorService executorService;

    private String getSuffix(String contentType) {
        return "mp4";
    }
}

